package br.ufrn.geologia.ggemma.model.extension;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import org.jspresso.framework.model.component.AbstractComponentExtension;

import br.ufrn.geologia.ggemma.model.Maintenance;
import br.ufrn.geologia.ggemma.model.MaintenanceExecution;

/**
 * Helper class computing extended properties for Maintenance entity.
 */
public class MaintenanceExtension extends AbstractComponentExtension<Maintenance> {

	private Date	last_execution	= null;

	private Integer	days_left	   = null;

	/**
	 * Constructs a new <code>MaintenanceExtension</code> instance.
	 * 
	 * @param extendedMaintenance
	 *            The extended maintenance instance.
	 */
	public MaintenanceExtension(Maintenance component) {
		super(component);
		registerNotificationForwarding(component, Maintenance.EXECUTIONS, Maintenance.LAST_EXECUTION);
		registerNotificationForwarding(component, Maintenance.EXECUTIONS, Maintenance.DAYS_LEFT);
		registerNotificationCollectionForwarding(component, Maintenance.EXECUTIONS, MaintenanceExecution.MAINTENANCE_DATE, Maintenance.LAST_EXECUTION);
		registerNotificationCollectionForwarding(component, Maintenance.EXECUTIONS, MaintenanceExecution.MAINTENANCE_DATE, Maintenance.DAYS_LEFT);
	}

	/**
	 * Computes the maintenances last execution date.
	 * 
	 * @return The maintenances last execution date.
	 */
	public Date getLast_execution() {
		if (maintenanceHasExecutions()) {
			List<MaintenanceExecution> executions = new ArrayList<>(getComponent().getExecutions());
			Collections.sort(executions, new Comparator<MaintenanceExecution>() {

				@Override
				public int compare(MaintenanceExecution o1, MaintenanceExecution o2) {
					if (o2.getMaintenance_date() != null) {
						if (o1.getMaintenance_date() != null) {
							return o2.getMaintenance_date().compareTo(o1.getMaintenance_date());
						}
						return 1;
					} else {
						if (o1.getMaintenance_date() != null) {
							return -1;
						}
						return 0;
					}
				}
			});
			last_execution = executions.get(0).getMaintenance_date();
		}
		return last_execution;
	}

	private boolean maintenanceHasExecutions() {
		return getComponent().getExecutions() != null && !getComponent().getExecutions().isEmpty();
	}

	/**
	 * Computes the maintenances last execution date.
	 * 
	 * @return The maintenances last execution date.
	 */
	public Integer getDays_left() {
		Maintenance maintenance = getComponent();
		if (maintenanceHasExecutions()) {
			Date lastExecution = maintenance.getLast_execution();
			if (lastExecution == null) {
				return 0;
			}
			Date today = new Date();
			days_left = (int) (maintenance.getInterval_in_days() - ((today.getTime() - lastExecution.getTime()) / (1000 * 60 * 60 * 24)));
		}
		return days_left;
	}

}
